package org.example;

import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
import com.drew.metadata.exif.ExifDirectoryBase;
import com.drew.metadata.exif.ExifIFD0Directory;
import com.drew.metadata.exif.ExifSubIFDDirectory;
import com.drew.metadata.exif.GpsDirectory;
import com.drew.metadata.jpeg.JpegDirectory;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpStatus;

import java.awt.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * https://blog.csdn.net/qq_36709470/article/details/119107457
 */
public class PictureInformationUtil {
    public static void main(String[] args) throws Exception, Exception {
        File file = new File("E:\\test\\img\\2021-06-01    014853    3.20120,   26.566000000.jpg");
        printImageTags(file);
        //imageExifModifier(file);
    }

    /**
     * https://blog.51cto.com/u_16213348/7002313
     */
    public static void imageExifModifier(File file) {
        try {
            Metadata metadata = ImageMetadataReader.readMetadata(file);

            // 获取EXIF子目录
            ExifSubIFDDirectory exifSubIFDDirectory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
            if (exifSubIFDDirectory != null) {
                // 修改拍摄时间
                exifSubIFDDirectory.setDate(ExifDirectoryBase.TAG_DATETIME_ORIGINAL, new Date());
            }

            // 获取EXIF IFD0目录
            ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
            if (exifIFD0Directory != null) {
                // 修改相机制造商名称
                exifIFD0Directory.setString(ExifDirectoryBase.TAG_MAKE, "Canon");
            }

            // 获取GPS目录
            GpsDirectory gpsDirectory = metadata.getFirstDirectoryOfType(GpsDirectory.class);
            if (gpsDirectory != null) {
                // 修改经纬度
                gpsDirectory.setDouble(GpsDirectory.TAG_LATITUDE, 39.9042);
                gpsDirectory.setString(GpsDirectory.TAG_LATITUDE_REF, "N");
                gpsDirectory.setDouble(GpsDirectory.TAG_LONGITUDE, 116.4074);
                gpsDirectory.setString(GpsDirectory.TAG_LONGITUDE_REF, "E");
            }

            // 获取JPEG目录
            JpegDirectory jpegDirectory = metadata.getFirstDirectoryOfType(JpegDirectory.class);
            if (jpegDirectory != null) {
                // 修改压缩质量
                jpegDirectory.setInt(JpegDirectory.TAG_COMPRESSION_TYPE, 90);
            }

//            // 保存修改后的图片
            File outputFile = new File("path/to/output.jpg");
            // 写入新的元数据到图片
            File tempFile = File.createTempFile("modified", ".jpg");
            //JpegWriter.writeMetadata(metadata, imageFile, tempFile);
        } catch (ImageProcessingException | IOException e) {
            System.err.println(e);
            e.printStackTrace();

        } catch (Exception e) {
            System.err.println(e);
            e.printStackTrace();
        }
    }

    /**
     * 读取照片里面的信息
     */
    private static void printImageTags(File file) throws ImageProcessingException, Exception {
        Metadata metadata = ImageMetadataReader.readMetadata(file);
        for (Directory directory : metadata.getDirectories()) {
            for (Tag tag : directory.getTags()) {
                String tagName = tag.getTagName();  //标签名
                String desc = tag.getDescription(); //标签信息
                if (tagName.equals("Image Height")) {
                    System.out.println("图片高度: " + desc);
                } else if (tagName.equals("Image Width")) {
                    System.out.println("图片宽度: " + desc);
                } else if (tagName.equals("Date/Time Original")) {
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");

                    System.out.println("拍摄时间: " + desc);
                    System.out.println("拍摄时间: " + dateFormat.parse(desc));
                } else if (tagName.equals("GPS Latitude")) {
                    System.err.println("纬度 : " + desc);
//                    System.err.println("纬度(度分秒格式) : "+pointToLatlong(desc));
                } else if (tagName.equals("GPS Longitude")) {
                    System.err.println("经度: " + desc);
//                    System.err.println("经度(度分秒格式): "+pointToLatlong(desc));
                }
            }
        }
    }

    /**
     * 经纬度格式  转换为  度分秒格式转换
     *
     * @param point 坐标点
     * @return
     */
    public String pointToLatlong(String point) {
        Double du = Double.parseDouble(point.substring(0, point.indexOf("°")).trim());
        Double fen = Double.parseDouble(point.substring(point.indexOf("°") + 1, point.indexOf("'")).trim());
        Double miao = Double.parseDouble(point.substring(point.indexOf("'") + 1, point.indexOf("\"")).trim());
        Double duStr = du + fen / 60 + miao / 60 / 60;
        return duStr.toString();
    }

    /**
     * 把byte转化为KB、MB、GB
     *
     * @param size
     * @return
     */
    public String getNetFileSizeDescription(long size) {
        StringBuffer bytes = new StringBuffer();
        DecimalFormat format = new DecimalFormat("###.00");
        if (size >= 1024L * 1024L * 1024L * 1024L) {
            double i = (size / (1024.0 * 1024.0 * 1024.0 * 1024.0));
            bytes.append(format.format(i)).append("TB");
        } else if (size >= 1024L * 1024L * 1024L) {
            double i = (size / (1024.0 * 1024.0 * 1024.0));
            bytes.append(format.format(i)).append("GB");
        } else if (size >= 1024L * 1024L) {
            double i = (size / (1024.0 * 1024.0));
            bytes.append(format.format(i)).append("MB");
        } else if (size >= 1024L) {
            double i = (size / (1024.0));
            bytes.append(format.format(i)).append("KB");
        } else if (size < 1024L) {
            bytes.append("0B");
        }
        return bytes.toString();
    }

    public static void getAddress(Map<String, String> param) {
//        String str = RequestUtils.sendGet("https://restapi.amap.com/v3/geocode/regeo", "key=5a3c45fd68d04bbc&location="+translate(param.get("GPS Longitude"))+","+translate(param.get("GPS Latitude")));
//        JSONObject result = JSON.parseObject(str);
//        System.out.println("拍摄时间：" +param.get("Date/Time"));
//        System.out.println("拍摄地点：" +result.getJSONObject("regeocode").getString("formatted_address"));
//        System.out.println("手机型号：" +param.get("Make") +" " + param.get("Model"));
//        System.out.println(str);
    }

    /**
     * 发送请求
     *
     * @param serverUrl 请求地址
     */
    private static String getResponse(String serverUrl) {
        // 用JAVA发起http请求，并返回json格式的结果
        StringBuffer result = new StringBuffer();
        try {
            URL url = new URL(serverUrl);
            URLConnection conn = url.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result.toString();
    }


    /**
     * 获取图片文件的Exif信息
     * https://blog.csdn.net/qq_40985985/article/details/118605888
     *
     * @param file
     * @return
     * @throws ImageProcessingException
     * @throws IOException
     */
    private static Map<String, String> readPicExifInfo(File file) throws ImageProcessingException, IOException {
        Map<String, String> map = new HashMap<>();
        Metadata metadata = ImageMetadataReader.readMetadata(file);
        for (Directory directory : metadata.getDirectories()) {
            for (Tag tag : directory.getTags()) {
                // 输出所有属性
                System.out.format(
                        "[%s] - %s = %s\n", directory.getName(), tag.getTagName(), tag.getDescription());
                map.put(tag.getTagName(), tag.getDescription());
            }
            if (directory.hasErrors()) {
                for (String error : directory.getErrors()) {
                    System.err.format("ERROR: %s", error);
                }
            }
        }
        return map;
    }

    /**
     * 打印照片Exif信息
     *
     * @param map
     */
    private static void printPicExifInfo(Map<String, String> map) {
        String[] strings = new String[]{"Compression", "Image Width", "Image Height", "Make", "Model", "Software",
                "GPS Version ID", "GPS Latitude", "GPS Longitude", "GPS Altitude", "GPS Time-Stamp", "GPS Date Stamp",
                "ISO Speed Ratings", "Exposure Time", "Exposure Mode", "F-Number", "Focal Length 35", "Color Space", "File Source", "Scene Type"};
        String[] names = new String[]{"压缩格式", "图像宽度", "图像高度", "拍摄手机", "型号", "手机系统版本号",
                "gps版本", "经度", "纬度", "高度", "UTC时间戳", "gps日期",
                "iso速率", "曝光时间", "曝光模式", "光圈值", "焦距", "图像色彩空间", "文件源", "场景类型"};
        for (int i = 0; i < strings.length; i++) {
            if (map.containsKey(strings[i])) {
                if ("GPS Latitude".equals(strings[i]) || "GPS Longitude".endsWith(strings[i])) {
                    System.out.println(names[i] + "  " + strings[i] + " : " + map.get(strings[i]) + ", °转dec: " + latLng2Decimal(map.get(strings[i])));
                } else {
                    System.out.println(names[i] + "  " + strings[i] + " : " + map.get(strings[i]));
                }
            }
        }

        // 经纬度转location地址信息
        if (map.containsKey("GPS Latitude") && map.containsKey("GPS Longitude")) {
            //convertLatLng2Loaction(latLng2Decimal(map.get("GPS Latitude")), latLng2Decimal(map.get("GPS Longitude")));
        }
    }

    /**
     * api_key：注册的百度api的key
     * coords：经纬度坐标
     * http://api.map.baidu.com/reverse_geocoding/v3/?ak="+api_key+"&output=json&coordtype=wgs84ll&location="+coords
     * <p>
     * 经纬度转地址信息
     *
     * @param gps_latitude
     * @param gps_longitude
     */
    private static void convertLatLng2Loaction(double gps_latitude, double gps_longitude) throws IOException {
        String apiKey = "FxzbLsuDDL4CS2U0M4KezOZZbGUY9iWtRn";

        String res = "";
        String url = "http://api.map.baidu.com/reverse_geocoding/v3/?ak=" + apiKey + "&output=json&coordtype=wgs84ll&location=" + (gps_latitude + "," + gps_longitude);
        System.out.println("【url】" + url);
        CloseableHttpClient client = HttpClients.custom().build();
        HttpGet httpPost = new HttpGet(url);
//        httpPost.setHeader("Content-Type", PageAttributes.MediaType.APPLICATION_JSON_VALUE);
//        CloseableHttpResponse resp = client.execute(httpPost);
//        if (resp != null) {
//            if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
//                HttpEntity entity = resp.getEntity();
//                res = IOUtils.readStreamAsString(entity.getContent());
//                System.out.println("resJson: " + res);
//                JSONObject object = JSONObject.parseObject(res);
//                if (object.containsKey("result")) {
//                    JSONObject result = object.getJSONObject("result");
//                    if (result.containsKey("addressComponent")) {
//                        JSONObject address = object.getJSONObject("result").getJSONObject("addressComponent");
//                        System.out.println("拍摄地点：" + address.get("country") + " " + address.get("province") + " " + address.get("city") + " " + address.get("district") + " "
//                                + address.get("street") + " " + result.get("formatted_address") + " " + result.get("business"));
//                    }
//                }
//            }
//        }
    }

    /***
     * 经纬度坐标格式转换（* °转十进制格式）
     * @param gps
     */
    public static double latLng2Decimal(String gps) {
        String a = gps.split("°")[0].replace(" ", "");
        String b = gps.split("°")[1].split("'")[0].replace(" ", "");
        String c = gps.split("°")[1].split("'")[1].replace(" ", "").replace("\"", "");
        double gps_dou = Double.parseDouble(a) + Double.parseDouble(b) / 60 + Double.parseDouble(c) / 60 / 60;
        return gps_dou;
    }


}
